﻿using EmotionsExtract.Emotion;
using EmotionsExtract.UITex;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace EmotionsExtract
{
    internal class Program
    {
        static void DeleteAll(string path)
        {
            DirectoryInfo directory = new DirectoryInfo(path);
            foreach (FileInfo file in directory.GetFiles("*", SearchOption.AllDirectories))
                file.Delete();
            foreach (DirectoryInfo dir in directory.GetDirectories("*", SearchOption.AllDirectories))
                dir.Delete(true);
        }

        static string ReplaceFileNameForURL(string fileName)
        {
            foreach (char i in "!*'();:@&=+$,/?#[]")
                fileName = fileName.Replace(i, '_');
            return fileName;
        }

        static void Main(string[] args)
        {
            int binarizeThreshold = 128;
            string inputDir = new DirectoryInfo(Path.GetFullPath(args[0])).FullName;
            string outputDir = new DirectoryInfo(Path.GetFullPath(args[1])).FullName;
            if(args.Length > 2)
                binarizeThreshold = int.Parse(args[2]);
            DeleteAll(outputDir);

            var catalog = new JArray();
            var uiTexs = new Dictionary<string, UITexFile>();
            var emotions = EmotionParser.Parse(Path.Combine(inputDir, "emotiontitle.txt"), Path.Combine(inputDir, "faceicon.txt"));
            foreach (var group in emotions)
            {
                JObject groupJson = new JObject();
                groupJson["group_id"] = group.ID;
                groupJson["group_name"] = group.Name;
                JArray items = new JArray();
                Directory.CreateDirectory(Path.Combine(outputDir, group.Name));
                foreach (var item in group.Emotions)
                {
                    JObject itemJson = new JObject();
                    itemJson["emotion_id"] = item.ID;
                    itemJson["key"] = item.Key;
                    itemJson["is_animated"] = item.IsAnimated;
                    string uiTexName = item.UITexName;
                    if (!uiTexs.ContainsKey(uiTexName))
                    {
                        Console.WriteLine($"Loading UITex: {uiTexName}");
                        uiTexs[uiTexName] = UITexFile.Load(Path.Combine(inputDir, "image", Path.ChangeExtension(uiTexName, ".uitex")));
                        Console.WriteLine($"Loaded UITex: {uiTexName}");
                    }
                    UITexFile uiTex = uiTexs[uiTexName];
                    string fileMainName = ReplaceFileNameForURL($"{group.ID}_{item.ID}_{item.Key}");
                    Console.WriteLine($"Processing {fileMainName}");
                    string outputRelativePath;
                    if (item.IsAnimated)
                    {
                        outputRelativePath = Path.Combine(group.Name, Path.ChangeExtension(fileMainName, ".gif"));
                        File.WriteAllBytes(Path.Combine(outputDir, outputRelativePath), uiTex.Animations[item.UITexFrame].GetImage(binarizeThreshold));
                    }
                    else
                    {
                        outputRelativePath = Path.Combine(group.Name, Path.ChangeExtension(fileMainName, ".png"));
                        uiTex.Frames[item.UITexFrame].GetImage().Save(Path.Combine(outputDir, outputRelativePath), System.Drawing.Imaging.ImageFormat.Png);
                    }
                    itemJson["filename"] = outputRelativePath.Replace("\\", "/");
                    items.Add(itemJson);
                    Console.WriteLine($"Processed {fileMainName}");
                }
                groupJson["items"] = items;
                catalog.Add(groupJson);
            }

            File.WriteAllText(Path.Combine(outputDir, "catalog.json"), catalog.ToString(Newtonsoft.Json.Formatting.Indented));

            foreach (var group in emotions)
            {
                string archiveName = Path.ChangeExtension(group.Name, ".zip");
                string sourceDir = Path.Combine(outputDir, group.Name);
                string targetArchive = Path.Combine(outputDir, archiveName);
                Console.WriteLine($"Archiving to {archiveName}");
                ZipFile.CreateFromDirectory(sourceDir, targetArchive, CompressionLevel.Optimal, false);
            }
        }
    }
}
